package com.admin.security.filter.login;


import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.alibaba.fastjson.JSON;
import com.admin.security.exception.UserLoginParamException;
import com.admin.utils.base.DataResult;
import com.admin.utils.base.RedisManager;
import com.admin.utils.base.ResponseFormatter;
import com.admin.utils.constant.GlobleSysUser;
import com.admin.utils.util.AjaxLoginParamDto;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * jwt用户登录处理
 * 
 * @author monxz
 *
 * @date 2019年10月25日
 */

public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter {

	private AuthenticationManager authenticationManager;
	

	private RedisManager redisManager;

	public JWTLoginFilter(AuthenticationManager authenticationManager,RedisManager redisManager) {
		super();
		this.authenticationManager = authenticationManager;
		this.redisManager= redisManager;
	}

	/**
	 * 请求登录
	 */
	@Override
	public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
			throws AuthenticationException {

		try {
			AjaxLoginParamDto dto = getParamByRequest(req);
			return authenticationManager.authenticate(
					new UsernamePasswordAuthenticationToken(dto.getUserName(), dto.getPassword(), new ArrayList<>()));
		} catch (Exception e) {
			ResponseFormatter.initResponse(res, DataResult.buildFail(e.getMessage()));
		}
		return null;
	}

	/**
	 * 登录成功
	 */
	@Override
	protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
			Authentication auth) throws IOException, ServletException {
		GlobleSysUser user = (GlobleSysUser) auth.getPrincipal();
		redisManager.set(user.getUserId(), JSON.toJSONString(user), 5000L);
		ResponseFormatter.initResponse(res, DataResult.buildSuccess(user.getUserId()+"@"+user.getLastTime()));
	}

	/**
	 * 从request中获取到登录请求
	 * 
	 * @param req
	 * @return
	 * @throws UserLoginParamException
	 */
	private AjaxLoginParamDto getParamByRequest(HttpServletRequest req) throws UserLoginParamException {
		BufferedReader br;
		StringBuffer loginJson = new StringBuffer();
		try {
			br = req.getReader();
			String str = "";
			while ((str = br.readLine()) != null) {
				loginJson.append(str);
			}
		} catch (IOException e1) {
			throw new UserLoginParamException("用户名/密码输入错误");
		}

		String formLogin = loginJson.toString();

		AjaxLoginParamDto dto = JSON.parseObject(formLogin, AjaxLoginParamDto.class);

		if (dto == null) {
			throw new UserLoginParamException("用户名/密码不能为空");
		}
		if (dto.getUserName() == null) {
			throw new UserLoginParamException("用户名不能为空");
		}

		if (dto.getPassword() == null) {
			throw new UserLoginParamException("密码不能为空");
		}

		return dto;
	}

}
